﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace MusicDownload
{
    public class Channel<T>
    {
        private List<T> list = new List<T>();

        private Mutex mutex = new Mutex();
        private object notFull = new object();
        private object notEmpty = new object();

        private int maxCount;

        public Channel() : this(1) { }

        public Channel(int count)
        {
            maxCount = count;
        }

        public void Push(T data)
        {
            Monitor.Enter(notFull);

            while (list.Count >= maxCount)
                Monitor.Wait(notFull);
            
            lock (list)
                list.Add(data);
            
            Monitor.Exit(notFull);
            
            lock (notEmpty)
            {
                if (list.Count > 0)
                    Monitor.PulseAll(notEmpty);
            }
        }

        public T Pop()
        {
            Monitor.Enter(notEmpty);

            while (list.Count == 0)
            {
                Monitor.Wait(notEmpty);
            }

            T first = default(T);
            lock (list)
            {
                first = list.First();
                list.RemoveAt(0);
            }
            
            Monitor.Exit(notEmpty);
            
            lock (notFull)
            {
                if (list.Count < maxCount)
                    Monitor.PulseAll(notFull);
            }

            return first;
        }
    }
}
